#include "shareManager.h"
#include "ui_quadcopter.h"

#include <QTimer>
#include <QDebug>
#include <QDialog>
#include <QDir>

#include <QStringList>
#include <QMessageBox>

#define  MASTER 198
#define  SLAVE  150
#define  X_OFFSET 48
#define  Y_OFFSET 0

Quadcopter::Quadcopter(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Quadcopter)
{
    ui->setupUi(this);
    setWindowTitle("XCopterHelper");

//Speedo------------------------------------
    speedo = new SpeedoMeter(this);
    speedo->setReadOnly(true);
    speedo->setGeometry(316 + X_OFFSET, 12, MASTER, MASTER);
    speedo->setLineWidth(5);
    speedo->setFocusPolicy(Qt::NoFocus);
    connect(speedo, SIGNAL(valueChanged(double)), ui->lcdNumber_speedo, SLOT(display(double)));
//Indicator---------------------------------
    indicator = new AttitudeIndicator( this );
    indicator->scaleDraw()->setPenWidth( 2 );
    indicator->setLineWidth(3);
    indicator->setGeometry(510 + X_OFFSET, 75, SLAVE, SLAVE);
    indicator->setFocusPolicy(Qt::NoFocus);
//Compass-----------------------------------
    compass = new QwtCompass(this);
    compass->setReadOnly(true);
    compass->setGeometry(170 + X_OFFSET, 75, SLAVE, SLAVE);
    compass->setLineWidth(5);
    compass->setFocusPolicy(Qt::NoFocus);
    compass->setNeedle( new QwtCompassMagnetNeedle(
        QwtCompassMagnetNeedle::TriangleStyle, Qt::white, Qt::red ) );

    QwtCompassScaleDraw *scaleDraw = new QwtCompassScaleDraw();
    scaleDraw->enableComponent( QwtAbstractScaleDraw::Ticks, true );
    scaleDraw->enableComponent( QwtAbstractScaleDraw::Labels, true );
    scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false );
    scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 0 );
    scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 0 );
    scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 3 );
    compass->setScaleDraw( scaleDraw );
//MAP---------------------------------------
    m_view = new QWebView(this);
    ui->verticalLayout_map->addWidget(m_view);
    m_view->settings()->setAttribute(QWebSettings::PluginsEnabled, true);
    m_view->settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
    m_view->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
    m_view->settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
    m_view->settings()->setAttribute(QWebSettings::JavaEnabled, true);
//UI小部件初始化------------------------------
    ui->verticalSlider_m1->setEnabled(false);
    ui->verticalSlider_m1->setFocusPolicy(Qt::NoFocus);
    ui->verticalSlider_m2->setEnabled(false);
    ui->verticalSlider_m2->setFocusPolicy(Qt::NoFocus);
    ui->verticalSlider_m3->setEnabled(false);
    ui->verticalSlider_m3->setFocusPolicy(Qt::NoFocus);
    ui->verticalSlider_m4->setEnabled(false);
    ui->verticalSlider_m4->setFocusPolicy(Qt::NoFocus);
    ui->verticalSlider_m5->setEnabled(false);
    ui->verticalSlider_m5->setFocusPolicy(Qt::NoFocus);
    ui->verticalSlider_m6->setEnabled(false);
    ui->verticalSlider_m6->setFocusPolicy(Qt::NoFocus);
//创建小部件---------------------------------
    pid = new SetPID(this);
    pid->setWindowTitle("PID");

    setting = new Setting(this);
    setting->setWindowTitle("设置");

    about = new About(this);
    about->setWindowTitle("关于");

//信号和槽等最后的初始化----------------------
    //启动按钮
    connect(ui->pushButton_startup, SIGNAL(clicked()), this, SLOT(slot_startup()));
    //校准按钮
    connect(ui->pushButton_cal, SIGNAL(clicked()), this, SLOT(slot_calibration()));
    //图传按钮
    connect(ui->pushButton_camera, SIGNAL(clicked()), this, SLOT(slot_videoTransfer()));
    //地图按钮
    connect(ui->pushButton_map, SIGNAL(clicked()), this, SLOT(on_pushButton_map_clicked()));

    //刷新UI定时器
    timer_tick = 0;
    tick_GPS = 0;
    tick_map = 0;
    connect(&rc_timer, SIGNAL(timeout()), this, SLOT(slot_update()));
}

Quadcopter::~Quadcopter()
{
    qDebug()<<"主线程析构";
    delete ui;
    delete speedo;
    delete compass;
    delete indicator;
}



void Quadcopter::on_pushButton_setting_clicked()
{
//    qDebug()<<setting->ui->tabWidget->currentWidget();
    setting->exec();
}

void Quadcopter::on_pushButton_setpid_clicked()
{
    pid->show();
}

void Quadcopter::on_pushButton_about_clicked()
{
    about->exec();
}

void Quadcopter::on_pushButton_map_clicked()
{
    m_view->setUrl(QUrl::fromLocalFile(QCoreApplication::applicationDirPath()+"/map.html"));//设置之后自动刷出来
    /*m_view->show();//不需要show*/
}

void Quadcopter::slot_startup()
{
    if(ui->pushButton_startup->text() == "停止")
    {
        sharePointer->serialThread.closeSerialPort();
        ui->pushButton_startup->setText("启动");
        return;
    }

    //WIFI or Serail MODE
    if(setting->isWIFI)
    {
        if(!sharePointer->tcpThread.connectServer(setting->ipAddress))
        {
            QMessageBox::critical(this, "WIFI", "打开失败！\n请检查连接和设置是否正确！", QMessageBox::Ok);
            return;
        }
    }else
    {
        if(!sharePointer->serialThread.openSerialPort(setting->serialPort))
        {
            QMessageBox::critical(this, "串口", "打开失败！\n请检查连接和设置是否正确！", QMessageBox::Ok);
            return;
        }
    }

    ui->pushButton_startup->setText("停止");

    //刷新定时器 最后启动
    rc_timer.start(10);
}

void Quadcopter::slot_videoTransfer()
{
    camera = new QProcess;
    QStringList args;

    args<<"";
    camera->start(QCoreApplication::applicationDirPath()+"/MJPG_Streamer.exe", args);//将MJPG放在同一目录
//    camera->start("E:/1Qt/201112701104/MJPG_Streamer-build-Desktop_Qt_5_0_1_MinGW_32bit-Release/release/MJPG_Streamer.exe", args);
}

void Quadcopter::slot_calibration()
{
    sharePointer->serialThread.sendCalibrationCMD();
    qDebug()<<"send cmd done.";
}

void Quadcopter::slot_update()
{
    tick_GPS++;
    tick_map++;
    timer_tick++;

    refreshAHRS();

    if(timer_tick >= 2)//20ms
    {
        timer_tick = 0;
        refreshRC();

        refreshMOTOR();
    }

    if(tick_GPS >= 10)//100ms
    {
        tick_GPS = 0;
        refreshGPS();
    }

    if(tick_map >= 50)//500ms
    {
        tick_map = 0;
        refreshMAP();
    }
}

void Quadcopter::refreshAHRS()
{
    if(!sharePointer->lockAHRS.tryLock(1))//等待1ms,失败马上返回,防止信号阻塞
    {return;}

    //仪表
    compass->setValue(sharePointer->AHRS_values.YAW + 180);//0 - 360
    indicator->setValue(-sharePointer->AHRS_values.ROL);
    indicator->setGradient(sharePointer->AHRS_values.PIT / 100);
    //标签
    ui->label_rolVal->setText(QString::number(sharePointer->AHRS_values.ROL));
    ui->label_pitVal->setText(QString::number(sharePointer->AHRS_values.PIT));
    ui->label_yawVal->setText(QString::number(sharePointer->AHRS_values.YAW));

    sharePointer->lockAHRS.unlock();
}

void Quadcopter::refreshRC()
{
    if(!sharePointer->lockRC.tryLock(1))
    {return;}

    qint16 temp = sharePointer->RC_Values.CH3 - 1000;
    if(temp < 0)//紧急制动
        {ui->progressBar_1->setValue(0);}
    else
        {ui->progressBar_1->setValue(temp>1000 ? 1000 : temp);}

    temp = sharePointer->RC_Values.CH1 - 1000;
    ui->progressBar_2->setValue(temp>1000 ? 1000 : temp);

    temp = sharePointer->RC_Values.CH4 - 1000;
    ui->progressBar_3->setValue(temp>1000 ? 1000 : temp);

    temp = sharePointer->RC_Values.CH2 - 1000;
    ui->progressBar_4->setValue(temp>1000 ? 1000 : temp);

    temp = sharePointer->RC_Values.CH6 - 1000;
    ui->progressBar_6->setValue(temp>1000 ? 1000 : temp);

    if(sharePointer->RC_Values.CH5 < 1250)
    {
        ui->progressBar_5->setValue(0);
    }else if(sharePointer->RC_Values.CH5 < 1750)
    {
        ui->progressBar_5->setValue(500);
    }else
    {
        ui->progressBar_5->setValue(1000);
    }

    if(sharePointer->RC_Values.CH7 < 1250)
    {
        ui->progressBar_7->setValue(0);
    }else if(sharePointer->RC_Values.CH7 < 1750)
    {
        ui->progressBar_7->setValue(500);
    }else
    {
        ui->progressBar_7->setValue(1000);
    }

    sharePointer->lockRC.unlock();
}

void Quadcopter::refreshGPS()
{
    if(!sharePointer->lockGPS.tryLock(1))
    {return;}

    if(sharePointer->GPS_values.satelNum > 0)
    {
        ui->label_lonVal->setText(QString::number(sharePointer->GPS_values.longtitude));
        ui->label_latVal->setText(QString::number(sharePointer->GPS_values.latitude));
        ui->label_eleVal->setText(QString::number(sharePointer->GPS_values.elevation));
        ui->label_speVal->setText(QString::number(sharePointer->GPS_values.speed));
        ui->label_satVal->setText(QString::number(sharePointer->GPS_values.satelNum));
    }else
    {
        ui->label_lonVal->setText("0.0");
        ui->label_latVal->setText("0.0");
        ui->label_eleVal->setText("0.0");
        ui->label_speVal->setText("0.0");
        ui->label_satVal->setText("0");
    }

    QString tmp = QString::fromLocal8Bit(sharePointer->GPS_values.time, -1);
    ui->label_timVal->setText(tmp.mid(0 , 2) + ":" + tmp.mid(2, 2) + ":" + tmp.mid(4,2));

    tmp = QString::fromLocal8Bit(sharePointer->GPS_values.date, 6);
    ui->label_datVal->setText(tmp.mid(0 , 2) + "/" + tmp.mid(2, 2) + "/20" + tmp.mid(4,2));

    sharePointer->lockGPS.unlock();
}

void Quadcopter::refreshMAP()
{
    static float lon, lat;
    //钉子按钮，决定是否定位，鼠标可以拖动来看地图
    //加一个判断，如果经纬度没有更新,或者卫星为0，立即返回

    if(sharePointer->GPS_values.satelNum == 0)
    {return;}

    if(sharePointer->GPS_values.latitude == lat && sharePointer->GPS_values.longtitude == lon)
    {return;}

    if(!sharePointer->lockGPS.tryLock(1))
    {return;}

    QWebFrame *frame = m_view->page()->mainFrame();
    QString cmd = QString("showAddress(\"%1\",\"%2\",\"1\");")
                    .arg(sharePointer->GPS_values.latitude).arg(sharePointer->GPS_values.longtitude);	//定位 不连续
    frame->evaluateJavaScript(cmd);

    lat = sharePointer->GPS_values.latitude;
    lon = sharePointer->GPS_values.longtitude;

    sharePointer->lockGPS.unlock();
}

void Quadcopter::refreshMOTOR()
{
    if(!sharePointer->lockMOTOR.tryLock(1))
    {return;}

    ui->verticalSlider_m1->setValue(sharePointer->MOTOR_values.motor1);
    ui->verticalSlider_m2->setValue(sharePointer->MOTOR_values.motor2);
    ui->verticalSlider_m3->setValue(sharePointer->MOTOR_values.motor3);
    ui->verticalSlider_m4->setValue(sharePointer->MOTOR_values.motor4);

    sharePointer->lockMOTOR.unlock();
}
